package com.qfedu.scode.service.impl;

import com.qfedu.scode.config.RedisKeyConfig;
import com.qfedu.scode.config.SystemConfig;
import com.qfedu.scode.dao.UserlogDao;
import com.qfedu.scode.dto.UserDto;
import com.qfedu.scode.entity.User;
import com.qfedu.scode.dao.UserDao;
import com.qfedu.scode.entity.Userlog;
import com.qfedu.scode.service.intf.UserService;
import com.qfedu.scode.util.*;
import com.qfedu.scode.vo.R;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * @program: StartCoding
 * @description: 一款真正的后端源码生成器，助力轻松入门Java程序
 * @author: Feri(老邢)
 * @create: 2021-01-06 11:09:45
 */
@Service
public class UserServiceImpl implements UserService{
    @Value("${scode.passkey}")
    private String key;
    /*
    *注入持久层对象*/
    @Autowired
    private UserDao dao;
    @Autowired
    private UserlogDao logDao;

    @Override
    public R checkPhone(String phone) {
//        Optional.ofNullable()
        //校验参数的合法性
        if(StringUtil.isNoEmpty(phone)) {
            //查询用户是否存在
            User user = dao.selectByPhone(phone);
            if (user == null) {
                return R.ok();
            }
        }
        //存在  非法 就不可用
        return R.fail();
    }

    @Override
    @Transactional //开启事务
    public R register(UserDto dto) {
        //校验参数的合法性
        if(StringUtil.isNoEmpty(dto.getPhone(),dto.getPassword())){
            //校验手机号是否唯一性
            if(dao.selectByPhone(dto.getPhone())==null){
                //可用  -密文
                //dto.setPassword();
                if(StringUtil.isNoEmpty(key)){
                    dto.setPassword(EncryptUtil.aesenc(key,dto.getPassword()));
                    User user=new User(dto.getPhone(),dto.getPassword());
                    if(dao.insert(user)>0){
                        logDao.insert(new Userlog(user.getId(), SystemConfig.USER_ADD,"用户注册，手机号："+dto.getPhone(),""));
                        return R.ok();
                    }
                }
            }
        }
        return R.fail();
    }

    /*
    * 查询 所有数据*/
    @Override
    public R queryAll() {
        return R.ok(dao.selectAll());
    }

    @Override
    public R login(UserDto dto) {
        //校验
        if(dto!=null){
            if(StringUtil.isNoEmpty(dto.getPhone(), dto.getPassword())){
                //唯一登陆
                //查询用户
                User user=dao.selectByPhone(dto.getPhone());
                //验证用户是否可用
                if(user!=null && user.getFlag()==SystemConfig.LOGIN_OK){
                    //验证密码
                    if(user.getPassword().equals(EncryptUtil.aesenc(key,dto.getPassword()))){
                        String phoneKey=RedisKeyConfig.LOGIN_PHONE+dto.getPhone();
                        //验证当前手机号是否在线 -确保唯一登陆
                        if(RedissonUtil.isHave(phoneKey)){
                            //在线-唯一登陆 需要把原来挤掉
                            String tk=RedissonUtil.getStr(phoneKey);
                            //删除原来的令牌
                            RedissonUtil.delKeys(RedisKeyConfig.LOGIN_TOKEN+tk);
                            //记录挤掉信息-方便推送
                            RedissonUtil.setHash(RedisKeyConfig.LOGIN_OUT,tk,"亲，你在"+ DateUtil.getTime()+"在其他设备上登陆");
                        }
                        //账号没问题- 生成令牌
                        String token= JwtUtil.createToken(user.getId()+"");
                        //存储Redis String 有效期 Key: val:
                        //令牌---用户
                        RedissonUtil.setStr(RedisKeyConfig.LOGIN_TOKEN+token,new JSONObject(user).toString(),RedisKeyConfig.LOGIN_TOKEN_TIMES);
                        //使用令牌和用户的token验证是否登录而不是手机号
                        //令牌和手机号，吧token存起来
                        RedissonUtil.setStr(RedisKeyConfig.LOGIN_PHONE+dto.getPhone(),token,RedisKeyConfig.LOGIN_TOKEN_TIMES);
                        //新增登陆日志
                        logDao.insert(new Userlog(user.getId(),SystemConfig.USER_LOGIN,"完成了登陆",""));
                        return R.ok(token);
                    }
                }
            }
        }
        return R.fail();
    }

    @Override
    public R checkToken(String token) {
        //检验
        if(StringUtil.isNoEmpty(token)){
            String key =RedisKeyConfig.LOGIN_TOKEN+token;
            //校验Redis 是否存在
            if(RedissonUtil.isHave(key)){

                return R.ok();
            }
        }
        return R.fail();
    }
}